import org.newdawn.slick.*;
import java.util.*;

public class MenuState implements ApplicationState {

	private int mouseX;
	private int mouseY;

	private int focused = Multitris.MENU_SINGLEPLAYER;

	private ApplicationStateManager stateMan;

	private int firstItemY = 200;
	private int itemSpacing = 70;

	private int logoY = 50;

	private boolean shift;

	private boolean showHelp;

	/**
	* Constructor for MenuState.
	*
	* @param manager The ApplicationStateManager controlling this instance.
	*/
	public MenuState(ApplicationStateManager manager) {
		stateMan = manager;
		if(Multitris.isApplet())
			firstItemY += 50;
	}


	/**
	* Informs the MenuState that the mouse has been moved.
	*
	* @param oldx The old x coordinate.
	* @param oldy The old y coordinate.
	* @param newx The new x coordinate.
	* @param newy The new y coordinate.
	*/
	public void mouseMoved(int oldx, int oldy, int newx, int newy) {
		mouseX = newx;
		mouseY = newy;

		if(!showHelp && mouseY > firstItemY && mouseY < firstItemY+itemSpacing*(Multitris.isApplet()?4:5) && mouseX > 150 && mouseX < 650) {
			focused = (mouseY-firstItemY)/itemSpacing+Multitris.MENU_SINGLEPLAYER;
		}
		else if(showHelp && mouseY > firstItemY+itemSpacing*4 && mouseY < firstItemY+itemSpacing*5 && mouseX > 150 && mouseX < 650) {
			focused = Multitris.MENU_BACK;
		}
	}

	/**
	* Informs the MenuState that a mouse button has been pressed.
	*
	* @param button The old mouse button pressed.
	* @param y The y coordinate.
	* @param x The x oordinate.
	*/
	public void mousePressed(int button, int x, int y) {
		mouseX = x;
		mouseY = y;

		boolean itemHover = false;
		if(!showHelp && mouseY > firstItemY && mouseY < firstItemY+itemSpacing*(Multitris.isApplet()?4:5) && mouseX > 150 && mouseX < 650) {
			itemHover = true;
		}
		else if(showHelp && mouseY > firstItemY+itemSpacing*4 && mouseY < firstItemY+itemSpacing*5 && mouseX > 150 && mouseX < 650) {
			itemHover = true;
		}
		if(itemHover)
			activateFocused();
	}

	/**
	* Renders the MenuState.
	*
	* @param g The graphics context to render to.
	*/
	public void render(Graphics g) {


		if(!showHelp) {
			g.drawImage(Multitris.menu[Multitris.MENU_LOGO][0], 400-Multitris.menu[Multitris.MENU_LOGO][0].getWidth()/2, logoY);

			for(int i=Multitris.MENU_SINGLEPLAYER; i<(Multitris.isApplet()?Multitris.MENU_EXIT:Multitris.MENU_EXIT+1); i++) {
				if(focused != i)
					g.drawImage(Multitris.menu[i][1], 400-Multitris.menu[i][0].getWidth()/2, firstItemY+itemSpacing*(i-Multitris.MENU_SINGLEPLAYER));
				else
					g.drawImage(Multitris.menu[i][0], 400-Multitris.menu[i][0].getWidth()/2, firstItemY+itemSpacing*(i-Multitris.MENU_SINGLEPLAYER));
			}

		} else {
			g.setColor(new Color(0,20,50,255));
			g.fillRoundRect(50,50,700,400,20);
			g.setColor(new Color(0,50,120,255));
			g.setAntiAlias(true);
			g.drawRoundRect(50,50,700,400,20);
			g.setAntiAlias(false);

			g.drawImage(Multitris.menu[Multitris.MENU_HELPSCREEN][0], 50,50);

			if(focused != Multitris.MENU_BACK)
				g.drawImage(Multitris.menu[Multitris.MENU_BACK][1], 400-Multitris.menu[Multitris.MENU_BACK][0].getWidth()/2, firstItemY+itemSpacing*(Multitris.MENU_EXIT-Multitris.MENU_SINGLEPLAYER));
			else
				g.drawImage(Multitris.menu[Multitris.MENU_BACK][0], 400-Multitris.menu[Multitris.MENU_BACK][0].getWidth()/2, firstItemY+itemSpacing*(Multitris.MENU_EXIT-Multitris.MENU_SINGLEPLAYER));

		}

	}

	/**
	* Updates the MenuState.
	*
	* @param delta The time passed since the last call to update.
	*/
	public void update(int delta) {

	}


	/**
	* Sets a mode for the state.
	*
	* @param parameter the mode to set.
	*/
	public void setMode(Object parameter) {
		Multitris.currentMusic.stop();
		Multitris.currentMusic = Multitris.music[Multitris.MUSIC_MENU];
		Multitris.currentMusic.loop();
		Multitris.currentMusic.setVolume(0.4f);
		if(!Multitris.musicEnabled) {
			Multitris.currentMusic.pause();
		}
	}

	/**
	* Informs the MenuState that an action has been requested.
	*
	* @param action The action requested.
	*/
	public void doInputAction(String action) {

		if(action.equals("p_shift")) {
			shift = true;
		}
		if(action.equals("r_shift")) {
			shift = false;
		}

		if(action.equals("p_tab")) {
			if(shift)
				action = "p_up";
			else
				action = "p_down";
		}

		if(action.equals("p_up")) {
			if(!showHelp) {
				focused = focused-1;
				if(focused < Multitris.MENU_SINGLEPLAYER)
					focused = (Multitris.isApplet()?Multitris.MENU_EXIT-1:Multitris.MENU_EXIT);
			}
		}
		if(action.equals("p_down")) {
			if(!showHelp) {
				focused = focused+1;
				if(focused > (Multitris.isApplet()?Multitris.MENU_EXIT-1:Multitris.MENU_EXIT))
					focused = Multitris.MENU_SINGLEPLAYER;
			}
		}
		if(action.startsWith("p_use")) {
			activateFocused();
		}
		if(action.equals("p_cancel") && showHelp) {
			focused = Multitris.MENU_BACK;
			activateFocused();
		}
		/*if(action.equals("p_cancel")) {
			focused = Multitris.MENU_EXIT;
			activateFocused();
		}*/
	}

	private void activateFocused() {
		if(focused == Multitris.MENU_EXIT) {
			exit();
		} else if (focused == Multitris.MENU_SINGLEPLAYER) {
			Multitris.gameServer = new GameServer(1000/Multitris.PULSES_PER_SECOND, 5398);
			System.out.println("Connecting to local game server");
			if (Multitris.clientCommunication.connectToGameServer("localhost", 5398, true)) {
				Multitris.clientCommunication.sendAction("start");
				Multitris.clientCommunication.localID = 0;

				int seed = (int)(Math.random()*Integer.MAX_VALUE);
				/*ArrayList<String> names = new ArrayList<String>();
				names.add("Local player");
				ArrayList<Integer> ids = new ArrayList<Integer>();
				ids.add(0);
				ArrayList<Color> colors = new ArrayList<Color>();
				colors.add(Color.red);
				ArrayList<Object> par = new ArrayList<Object>();
				par.add(names);
				par.add(ids);
				par.add(colors);*/

				HashMap<Integer, Client> clientList = new HashMap<Integer, Client>();
				clientList.put(0, new Client(0, "Local player", Color.red));

				ArrayList<Object> par = new ArrayList<Object>();
				par.add(clientList);
				par.add(seed);

				stateMan.switchState(ApplicationStateManager.GAME, par);
			} else {
				System.err.println("Failed to connect to local game server");
			}
		} else if(focused == Multitris.MENU_HOSTGAME) {
			stateMan.switchState(ApplicationStateManager.LOBBY, new Integer(LobbyState.HOST));
		}
		else if(focused == Multitris.MENU_JOINGAME) {
			stateMan.switchState(ApplicationStateManager.LOBBY, new Integer(LobbyState.LIST));
		}
		else if(focused == Multitris.MENU_HELP) {
			showHelp = true;
			focused = Multitris.MENU_BACK;
		}
		else if(focused == Multitris.MENU_BACK) {
			showHelp = false;
			focused = Multitris.MENU_SINGLEPLAYER;
		}
	}

	private void exit() {
		System.exit(0);
	}
}